home *** CD-ROM | disk | FTP | other *** search
/ Aminet 41 / Aminet 41 (2001)(Schatztruhe)[!][Feb 2001].iso / Aminet / dev / c / libiconv_src.lha / src / iso2022_jp1.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-11-07  |  5.4 KB  |  242 lines

  1.  
  2. /*
  3.  * ISO-2022-JP-1
  4.  */
  5.  
  6. /* Specification: RFC 2237 */
  7.  
  8. #define ESC 0x1b
  9.  
  10. /*
  11.  * The state can be one of the following values.
  12.  */
  13. #define STATE_ASCII          0
  14. #define STATE_JISX0201ROMAN  1
  15. #define STATE_JISX0208       2
  16. #define STATE_JISX0212       3
  17.  
  18. static int
  19. iso2022_jp1_mbtowc (conv_t conv, wchar_t *pwc, const unsigned char *s, int n)
  20. {
  21.   state_t state = conv->istate;
  22.   int count = 0;
  23.   unsigned char c;
  24.   for (;;) {
  25.     c = *s;
  26.     if (c == ESC) {
  27.       if (n < count+3)
  28.         goto none;
  29.       if (s[1] == '(') {
  30.         if (s[2] == 'B') {
  31.           state = STATE_ASCII;
  32.           s += 3; count += 3;
  33.           if (n < count+1)
  34.             goto none;
  35.           continue;
  36.         }
  37.         if (s[2] == 'J') {
  38.           state = STATE_JISX0201ROMAN;
  39.           s += 3; count += 3;
  40.           if (n < count+1)
  41.             goto none;
  42.           continue;
  43.         }
  44.         return RET_ILSEQ;
  45.       }
  46.       if (s[1] == '$') {
  47.         if (s[2] == '@' || s[2] == 'B') {
  48.           /* We don't distinguish JIS X 0208-1978 and JIS X 0208-1983. */
  49.           state = STATE_JISX0208;
  50.           s += 3; count += 3;
  51.           if (n < count+1)
  52.             goto none;
  53.           continue;
  54.         }
  55.         if (s[2] == '(') {
  56.           if (n < count+4)
  57.             goto none;
  58.           if (s[3] == 'D') {
  59.             state = STATE_JISX0212;
  60.             s += 4; count += 4;
  61.             if (n < count+1)
  62.               goto none;
  63.             continue;
  64.           }
  65.         }
  66.         return RET_ILSEQ;
  67.       }
  68.       return RET_ILSEQ;
  69.     }
  70.     break;
  71.   }
  72.   switch (state) {
  73.     case STATE_ASCII:
  74.       if (c < 0x80) {
  75.         int ret = ascii_mbtowc(conv,pwc,s,1);
  76.         if (ret == RET_ILSEQ)
  77.           return RET_ILSEQ;
  78.         if (ret != 1) abort();
  79.         conv->istate = state;
  80.         return count+1;
  81.       } else
  82.         return RET_ILSEQ;
  83.     case STATE_JISX0201ROMAN:
  84.       if (c < 0x80) {
  85.         int ret = jisx0201_mbtowc(conv,pwc,s,1);
  86.         if (ret == RET_ILSEQ)
  87.           return RET_ILSEQ;
  88.         if (ret != 1) abort();
  89.         conv->istate = state;
  90.         return count+1;
  91.       } else
  92.         return RET_ILSEQ;
  93.     case STATE_JISX0208:
  94.       if (n < count+2)
  95.         goto none;
  96.       if (s[0] < 0x80 && s[1] < 0x80) {
  97.         int ret = jisx0208_mbtowc(conv,pwc,s,2);
  98.         if (ret == RET_ILSEQ)
  99.           return RET_ILSEQ;
  100.         if (ret != 2) abort();
  101.         conv->istate = state;
  102.         return count+2;
  103.       } else
  104.         return RET_ILSEQ;
  105.     case STATE_JISX0212:
  106.       if (n < count+2)
  107.         goto none;
  108.       if (s[0] < 0x80 && s[1] < 0x80) {
  109.         int ret = jisx0212_mbtowc(conv,pwc,s,2);
  110.         if (ret == RET_ILSEQ)
  111.           return RET_ILSEQ;
  112.         if (ret != 2) abort();
  113.         conv->istate = state;
  114.         return count+2;
  115.       } else
  116.         return RET_ILSEQ;
  117.     default: abort();
  118.   }
  119.  
  120. none:
  121.   conv->istate = state;
  122.   return RET_TOOFEW(count);
  123. }
  124.  
  125. static int
  126. iso2022_jp1_wctomb (conv_t conv, unsigned char *r, wchar_t wc, int n)
  127. {
  128.   state_t state = conv->ostate;
  129.   unsigned char buf[2];
  130.   int ret;
  131.  
  132.   /* Try ASCII. */
  133.   ret = ascii_wctomb(conv,buf,wc,1);
  134.   if (ret != RET_ILSEQ) {
  135.     if (ret != 1) abort();
  136.     if (buf[0] < 0x80) {
  137.       int count = (state == STATE_ASCII ? 1 : 4);
  138.       if (n < count)
  139.         return RET_TOOSMALL;
  140.       if (state != STATE_ASCII) {
  141.         r[0] = ESC;
  142.         r[1] = '(';
  143.         r[2] = 'B';
  144.         r += 3;
  145.         state = STATE_ASCII;
  146.       }
  147.       r[0] = buf[0];
  148.       conv->ostate = state;
  149.       return count;
  150.     }
  151.   }
  152.  
  153.   /* Try JIS X 0201-1976 Roman. */
  154.   ret = jisx0201_wctomb(conv,buf,wc,1);
  155.   if (ret != RET_ILSEQ) {
  156.     if (ret != 1) abort();
  157.     if (buf[0] < 0x80) {
  158.       int count = (state == STATE_JISX0201ROMAN ? 1 : 4);
  159.       if (n < count)
  160.         return RET_TOOSMALL;
  161.       if (state != STATE_JISX0201ROMAN) {
  162.         r[0] = ESC;
  163.         r[1] = '(';
  164.         r[2] = 'J';
  165.         r += 3;
  166.         state = STATE_JISX0201ROMAN;
  167.       }
  168.       r[0] = buf[0];
  169.       conv->ostate = state;
  170.       return count;
  171.     }
  172.   }
  173.  
  174.   /* Try JIS X 0208-1990 in place of JIS X 0208-1978 and JIS X 0208-1983. */
  175.   ret = jisx0208_wctomb(conv,buf,wc,2);
  176.   if (ret != RET_ILSEQ) {
  177.     if (ret != 2) abort();
  178.     if (buf[0] < 0x80 && buf[1] < 0x80) {
  179.       int count = (state == STATE_JISX0208 ? 2 : 5);
  180.       if (n < count)
  181.         return RET_TOOSMALL;
  182.       if (state != STATE_JISX0208) {
  183.         r[0] = ESC;
  184.         r[1] = '$';
  185.         r[2] = 'B';
  186.         r += 3;
  187.         state = STATE_JISX0208;
  188.       }
  189.       r[0] = buf[0];
  190.       r[1] = buf[1];
  191.       conv->ostate = state;
  192.       return count;
  193.     }
  194.   }
  195.  
  196.   /* Try JIS X 0212-1990. */
  197.   ret = jisx0212_wctomb(conv,buf,wc,2);
  198.   if (ret != RET_ILSEQ) {
  199.     if (ret != 2) abort();
  200.     if (buf[0] < 0x80 && buf[1] < 0x80) {
  201.       int count = (state == STATE_JISX0212 ? 2 : 6);
  202.       if (n < count)
  203.         return RET_TOOSMALL;
  204.       if (state != STATE_JISX0212) {
  205.         r[0] = ESC;
  206.         r[1] = '$';
  207.         r[2] = '(';
  208.         r[3] = 'D';
  209.         r += 4;
  210.         state = STATE_JISX0212;
  211.       }
  212.       r[0] = buf[0];
  213.       r[1] = buf[1];
  214.       conv->ostate = state;
  215.       return count;
  216.     }
  217.   }
  218.  
  219.   return RET_ILSEQ;
  220. }
  221.  
  222. static int
  223. iso2022_jp1_reset (conv_t conv, unsigned char *r, int n)
  224. {
  225.   state_t state = conv->ostate;
  226.   if (state != STATE_ASCII) {
  227.     if (n < 3)
  228.       return RET_TOOSMALL;
  229.     r[0] = ESC;
  230.     r[1] = '(';
  231.     r[2] = 'B';
  232.     /* conv->ostate = 0; will be done by the caller */
  233.     return 3;
  234.   } else
  235.     return 0;
  236. }
  237.  
  238. #undef STATE_JISX0212
  239. #undef STATE_JISX0208
  240. #undef STATE_JISX0201ROMAN
  241. #undef STATE_ASCII
  242.